const { regClass } = Laya;
import { CONFIG_GAME_ADS_ADD_TIME, CONFIG_VIDEO_URL } from "../../Data/Config";
import { LevelConfig, LevelConfigInfo } from "../../Data/LevelConfig";
import { StaticData } from "../../Data/StaticData";
import { GameRes } from "../../GameRes";
import HttpAPI from "../../HttpManager/HttpAPI";
import HttpManager from "../../HttpManager/HttpManager";
import { EventNames } from "../Data/EventNames";
import { EState } from "./ListImg/GameListImg";
import { ClickPoint, NodeDifferentState } from "./ClickPoint";
import { ViewGameRunBase } from "./ViewGameRun.generated";

@regClass()
export class ViewGameRun extends ViewGameRunBase {
    /** 预制体 */
    resItemNodeDifferent: Laya.Prefab;
    /** UI */
    arrItemDifferent: ClickPoint[] = [];
    /** UI */
    boxCanvas: Laya.Box;

    /** 游戏配置 */
    gameConfig: LevelConfigInfo;
    /** 上一帧的时间 */
    lastTime: number = undefined;
    /** 是否运行倒计时 */
    isRunTime: boolean = false;
    /** 当前时间计时 */
    nowTime: number = 0;
    /** 最大时间计时 */
    maxTime: number = 60;
    /** 加时附加的时间。用于最后时间统计时记录正确的时间而不是负数时间 */
    addTime: number = 0;

    /** 当前进度 */
    nowProgress: number = 0;
    /** 最大进度 */
    maxProgress: number = 0;
    /** 答题记录 */
    selectCtrl: Array<{ id: number, selectID: number, trueID: number }> = [];

    onAwake(): void {
        this.boxCanvas = this;
        this.resItemNodeDifferent = GameRes.getResPrefab(GameRes.ItemClickPoint);

        this.BtnBack.on(Laya.Event.CLICK, this, this.onClickBack)
        this.BtnSet.on(Laya.Event.CLICK, this, this.onClickSet)
        this.BtnTip.on(Laya.Event.CLICK, this, this.onClickTip)
        this.BtnAddTime.on(Laya.Event.CLICK, this, this.onClickAddTime)
        Laya.stage.on(EventNames.GAME_AGAIN, this, this.eventGameAgain)
        Laya.stage.on(EventNames.GAME_GO_HOME, this, this.eventGameGoHome)
        Laya.stage.on(EventNames.GAME_NEXT, this, this.eventGameNext)

        this.PopSelectExceptionMessage.visible = false;
        this.PopSelectExceptionMessage.actSelect = this.onSelectExcepotion.bind(this);
        this.GameImgList.init(this.onClickShowHide.bind(this));
        this.GameImgList.setType(EState.hide);
        this.onClickShowHide(EState.hide);
        this.PopGameOver.hideView();
        this.ViewVideoNode.hideView();


        this.timer.frameLoop(1, this, this.upDate);
        this.nowTime = 0;
        this.refishTime();
        this.refishProgress();
    }
    onDestroy(): void {
        this.BtnBack.off(Laya.Event.CLICK, this, this.onClickBack)
        this.BtnSet.off(Laya.Event.CLICK, this, this.onClickSet)
        this.BtnTip.off(Laya.Event.CLICK, this, this.onClickTip)
        this.BtnAddTime.off(Laya.Event.CLICK, this, this.onClickAddTime)
        Laya.stage.off(EventNames.GAME_AGAIN, this, this.eventGameAgain)
        Laya.stage.off(EventNames.GAME_GO_HOME, this, this.eventGameGoHome)
        Laya.stage.off(EventNames.GAME_NEXT, this, this.eventGameNext)
    }

    showView(config: LevelConfigInfo) {
        this.clearItem();
        this.gameConfig = config;
        this.gameInit();
        this.visible = true;
        this.isRunTime = true;
        console.log("showView=>", config);
        this.PopSelectExceptionMessage.createItem(config.arrLevelQuestion);

        if (StaticData.userGameGuide) {
            this.ViewGuide.viewHide();
        } else {
            HttpManager.get(HttpAPI.GET_UPDATE_GUIDE).then((res) => {
                if (res.success) {
                    console.log("更新新手引导成功");
                    StaticData.userGameGuide = 1
                }
            });
            this.ViewGuide.viewShow((() => { }).bind(this));
        }
    }

    hideView() {
        this.clearItem();
        this.visible = false;
    }


    private onClickItem(id: number) {
        this.isRunTime = true;
        console.log("点击异常", id);
        if (this.arrItemDifferent[id].type == NodeDifferentState.success) { console.log("这个", id, "已经成功了。不再处理后续逻辑"); return; }
        this.arrItemDifferent[id].setType(NodeDifferentState.Select);
        // 图像的中心点
        let x = this.arrItemDifferent[id].x + this.arrItemDifferent[id].width / 2;
        let y = this.arrItemDifferent[id].y + this.arrItemDifferent[id].height / 2;
        /** 拿到相对屏幕左上角(0,0)的坐标 */
        const pos = this.TouchPanel.getSceneXY(x, y)
        let endX = pos.x;

        // 已知Item的中心点在屏幕上是pos。需要偏移自己身的宽度 + 间距 + Pop的宽度/2
        let r = pos.x + this.arrItemDifferent[id].width * this.TouchPanel.nowScale / 2 + 10 + this.PopSelectExceptionMessage.popWidth;
        if (r > this.boxCanvas.width) {
            console.log("右侧超出了屏幕");
            endX = pos.x - this.arrItemDifferent[id].width * this.TouchPanel.nowScale / 2 - this.PopSelectExceptionMessage.popWidth - 10;
            if (endX < 0) {
                console.log("左侧也超了");
                endX = 0;
            }
        } else {
            endX = pos.x + this.arrItemDifferent[id].width * this.TouchPanel.nowScale / 2 + 10;
        }

        let t = pos.y - this.PopSelectExceptionMessage.popHeight / 2;
        let d = pos.y + this.PopSelectExceptionMessage.popHeight / 2;
        let endY = pos.y;
        if (t < 0) {
            console.log("上方超出屏幕");
            endY = 0;
        } else if (d > this.boxCanvas.height) {
            console.log("下方超出屏幕");
            endY = this.boxCanvas.height - this.PopSelectExceptionMessage.popHeight
        } else {
            console.log("在中间");
            endY = pos.y - this.PopSelectExceptionMessage.popHeight / 2;
        }


        this.PopSelectExceptionMessage.popX = endX;
        this.PopSelectExceptionMessage.popY = endY;
        this.PopSelectExceptionMessage.showPop(id, this.gameConfig.arrLevelQuestion[id]);
    }
    private onSelectExcepotion(id: number, selectId: number, trueId: number, success: boolean) {
        console.log("本题", id, "选择了", selectId, "，正确答案是", trueId, "。结果：", success);
        if (selectId == -1) {
            // 未选择
            this.arrItemDifferent[id].setType(NodeDifferentState.Select);
        } else if (!success) {
            // 选择错误
            this.arrItemDifferent[id].setType(NodeDifferentState.err);
            this.arrItemDifferent[id].aniToSelcet();
            this.PopSelectExceptionMessage.aniToSelcet();
            this.selectCtrl.push({
                id: id,
                selectID: selectId,
                trueID: trueId
            })
        } else if (success) {
            // 选择正确
            this.arrItemDifferent[id].setType(NodeDifferentState.success);
            this.selectCtrl.push({
                id: id,
                selectID: selectId,
                trueID: trueId
            })
            console.log("选择正确", id, "=>", this.gameConfig.arrLevelQuestion[id]);
            this.GameImgList.setTexture(id, this.TouchPanel.getTexture(this.gameConfig.arrLevelQuestion[id]))

            let count = 0;
            for (let item of this.arrItemDifferent) {
                if (item.type == NodeDifferentState.success) {
                    count++;
                }
            }
            this.nowProgress = count;
            this.refishProgress();
            if (this.nowProgress >= this.maxProgress) {
                console.log("题目答题完成,GameOver");
                this.gameOver(true)
            }
        }

    }

    private onClickShowHide(type: EState) {
        console.log("弹窗状态", type);
        if (type == EState.hide) {
            this.BoxDown.bottom = - this.BoxDown.height;
        } else if (type == EState.show) {
            this.BoxDown.bottom = 0;
        }
    }

    private onClickBack() {
        Laya.SoundManager.playSound(GameRes.clickAudio, 1);
        this.isRunTime = false;
        Laya.stage.event(EventNames.POPUP_SHOW_COMMON_YES_NO, {
            msg: "返回后本关进度将不会保存！",
            yes: () => {
                Laya.stage.event(EventNames.GAME_GO_HOME);
            },
            no: () => {
                this.isRunTime = true;
            }
        }
        );
    }

    private onClickSet() {
        Laya.SoundManager.playSound(GameRes.clickAudio, 1);
        this.isRunTime = false;
        console.log("时间暂停");
        Laya.stage.event(EventNames.GAME_OPEN_SET, (() => {
            this.isRunTime = true;
            console.log("时间继续");
        }).bind(this));
    }

    private onClickTip() {
        Laya.SoundManager.playSound(GameRes.clickAudio, 1);
        console.log("提示");
        console.log("播放测试视频链接" + CONFIG_VIDEO_URL);
        this.isRunTime = false;
        this.ViewVideoNode.showView(CONFIG_VIDEO_URL, (isEnd) => {
            this.isRunTime = true;
            this.ViewVideoNode.hideView();
            if (!isEnd) { console.log("未看完视频"); return; }
            console.log("触发提示");
            let isTip = false;
            for (let item of this.arrItemDifferent) {
                if (item.type == NodeDifferentState.Tip) {
                    continue;
                }
                if (item.type != NodeDifferentState.success) {
                    item.setType(NodeDifferentState.Tip);
                    isTip = true;
                    this.TouchPanel.moveTo(item.x + item.width / 2, item.y + item.height / 2)
                    break;
                }
            }
            if (isTip) {
                // 触发了提示信息
            } else {
                //
                console.log("没有提示，所以触发加时");
                this.nowTime += CONFIG_GAME_ADS_ADD_TIME;
                this.addTime += CONFIG_GAME_ADS_ADD_TIME;
            }
        });
    }
    private onClickAddTime() {
        Laya.SoundManager.playSound(GameRes.clickAudio, 1);
        console.log("播放测试视频链接" + CONFIG_VIDEO_URL);
        console.log(" this.nowTime", this.nowTime);
        this.isRunTime = false;
        this.ViewVideoNode.showView(CONFIG_VIDEO_URL, (isEnd) => {
            this.isRunTime = true;
            if (!isEnd) { console.log("未看完视频"); return; }
            console.log(" this.nowTime", this.nowTime);
            console.log("触发加时");
            this.ViewVideoNode.hideView();
            this.nowTime += CONFIG_GAME_ADS_ADD_TIME;
            this.addTime += CONFIG_GAME_ADS_ADD_TIME;
            console.log(" this.nowTime", this.nowTime);
        });
    }
    private loadImgOver() {
        for (let i = 0; i < this.gameConfig.arrLevelQuestion.length; i++) {
            let cfg = this.gameConfig.arrLevelQuestion[i];
            let obj = this.resItemNodeDifferent.create() as ClickPoint
            this.TouchPanel.addDifferent(obj)
            obj.setInfo(i, this.onClickItem.bind(this));
            obj.x = cfg.questionX * this.TouchPanel.marginSc;
            obj.y = cfg.questionY * this.TouchPanel.marginSc;
            obj.width = cfg.questionWidth * this.TouchPanel.marginSc;
            obj.height = cfg.questionHeight * this.TouchPanel.marginSc;
            this.arrItemDifferent.push(obj);
        }
    }
    private gameInit() {
        this.clearItem();

        this.nowProgress = 0;
        this.nowTime = this.maxTime;
        this.addTime = 0;
        this.maxProgress = this.gameConfig.arrLevelQuestion.length;
        this.selectCtrl = [];

        this.TouchPanel.loadTexture(this.gameConfig.barrierImgUrl, this.loadImgOver.bind(this))
        this.GameImgList.setInfo(this.gameConfig);

        this.refishTime();
        this.refishProgress();
        this.GameImgList.setType(EState.hide);
        this.onClickShowHide(EState.hide);
        this.PopSelectExceptionMessage.hidePop();
    }

    private gameOver(isWin: boolean) {
        this.isRunTime = false;
        let errCount = 0;
        const errOneScore = 1;
        for (let item of this.selectCtrl) {
            if (item.selectID != item.trueID) {
                errCount++;
            }
        }
        const maxErrCount = Math.ceil(this.gameConfig.arrLevelQuestion.length / 2);
        if (errCount > maxErrCount) {
            errCount = maxErrCount;
        }
        const score = (this.gameConfig.arrLevelQuestion.length - errCount) * errOneScore;

        console.log("发送接口");
        console.log("本题总计" + this.gameConfig.arrLevelQuestion.length + "条，错误" + errCount + "条，得分" + score + "分");


        const answerTime = this.nowTime;
        let arrAnswer = [];
        for (let item of this.selectCtrl) {
            arrAnswer.push({
                /** 下标从1开始 */
                answerId: item.id + 1,
                /** 下标从1开始 */
                selectId: item.selectID + 1,
            });
        }
        console.log("arrAnswer=>", arrAnswer);

        HttpManager.post(HttpAPI.POST_GAME_OVER, {
            barrierId: this.gameConfig.id,
            answerTime: answerTime <= 0 ? 0 : answerTime,
            answer: arrAnswer
        }, null).then(this.senndOver.bind(this)).catch(this.senndOver.bind(this));
    }


    private upDate() {
        if (this.lastTime == undefined) {
            this.lastTime = Date.now();
            return;
        }
        const dt = (Date.now() - this.lastTime) / 1000;
        this.lastTime = Date.now();

        this.autoTimeRun(dt);

    }

    private autoTimeRun(dt: number) {
        if (!this.isRunTime) {
            return;
        }

        this.nowTime -= dt;
        this.refishTime();

        if (this.nowTime <= 0) {
            this.nowTime = 0;
            this.refishTime();
            console.log("时间到");
            this.gameOver(false);
            this.isRunTime = false;
        }
    }

    private refishTime() {
        this.TxtTime.text = "" + Math.ceil(this.nowTime);
    }

    private refishProgress() {
        this.TxtNowProgress.text = "" + this.nowProgress;
        this.TxtMaxProgress.text = "/" + this.maxProgress;
        if (this.gameConfig == null || this.gameConfig == undefined) { return; }
        if (this.gameConfig.tips == null || this.gameConfig.tips == undefined || this.gameConfig.tips.length == 0) {
            this.TxtTitle2.text = "(找到场景中不符合规范的" + this.maxProgress + "个地方)";
        } else {
            this.TxtTitle2.text = this.gameConfig.tips[0];//"(找到场景中不符合规范的" + this.maxProgress + "个地方)";
        }
    }

    private clearItem() {
        /** 清理游戏内的选项 */
        while (this.arrItemDifferent.length > 0) {
            let item = this.arrItemDifferent.pop();
            item.destroy();
        }
    }

    private eventGameAgain() {
        console.log("再次游玩当前关卡", this.gameConfig);
        this.gameInit();
        this.isRunTime = true;
    }
    private eventGameGoHome() { console.log("返回主页"); this.hideView(); }
    private eventGameNext() {
        if (LevelConfig.getNextLevelId(this.gameConfig.id) == -1) {
            console.log("没有下一关了");
            Laya.stage.event(EventNames.GAME_GO_HOME);
            return;
        }
        StaticData.getLevelConfig(LevelConfig.getNextLevelId(this.gameConfig.id), (config) => {
            if (!config) {
                console.log("关卡配置异常");
                Laya.stage.event(EventNames.GAME_GO_HOME);
                return
            }
            console.log("下一关1", this);
            this.gameConfig = config;
            this.gameInit();
            this.isRunTime = true;
        })
    }
    private senndOver(data: any) {
        if (data && data.success) {
            const result = data.result;
            this.PopGameOver.showView(result.success, Math.ceil((this.maxTime + this.addTime) - this.nowTime), result.afterIntegral - result.beforeIntegral);
        } else {

            Laya.stage.event(EventNames.GAME_GO_HOME)
            Laya.stage.event(EventNames.POPUP_SHOW_COMMON_TIPS, "关卡结算失败!!!")
        }
    }

}